package com.jintian.smart.kernel.common.expr;

import com.jintian.smart.kernel.common.expr.datameta.Variable;
import com.jintian.smart.kernel.common.expr.function.FunctionExecution;
import com.jintian.smart.kernel.core.expr.IExpressionCalc;
import com.jintian.smart.kernel.core.expr.IFunctionRepository;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

public class IKExpressionCalc implements IExpressionCalc, InitializingBean {
    @Autowired(required = false)
    private IFunctionRepository IFunctionRepository;

    private FunctionExecution functionExecution;

    @Override
    public void setFunctionRepository(IFunctionRepository IFunctionRepository) {
        this.IFunctionRepository = IFunctionRepository;
    }

    @Override
    public Object calculate(String expr, Map<String, Object> variants) {
        this.getLocalContext().entrySet().stream().forEach(e -> {
            ExpressionEvaluator.addVarible(Variable.createVariable(e.getKey(), e.getValue()));
        });
        if (variants != null) {
            variants.entrySet().stream().forEach(e -> {
                ExpressionEvaluator.addVarible(Variable.createVariable(e.getKey(), e.getValue()));
            });
        }
        FunctionExecution.bind(functionExecution);
        try {
            return ExpressionEvaluator.evaluate(expr, null);
        } finally {
            FunctionExecution.unbind();
        }

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (this.functionExecution == null) {
            if (this.IFunctionRepository != null) {
                this.functionExecution = new FunctionExecution(this.IFunctionRepository);
            } else {
                this.functionExecution = new FunctionExecution();
            }
        }

    }

    @Override
    public void reloadFunctions() {
        this.functionExecution.setFunctionRepository(IFunctionRepository);
    }
}
